/**
 **oj/doc - Online documentation generator
 *
 * The doc module automatically generates documentation from oj modules.
 *
 */

define(['oj/os', 'oj/file', 'oj/javascript'], function(os, file, javascript) {
    
    window['doc'] = {}
        
    var COMMENTBLOCKS = /\/\*\*[\s\S]*?\*\//gm,
        COMMENTLINE   = /\n\s*\*[^\n]*/gm,
        TRIMLINE      = /\n\s*\*/gm,
        WHITESPACE    = /\s/gm,
        ANCHORREM     = /[ "'\[\]\)?{}]/g,
        ANCHORREP     = /[,\(]/g
    
    
    
    function libraryIndex(libraryName, libraryPath, container, url, module) {
        os.read(libraryPath, function (result) {
            var table,
                name
            
            if (oj.isError(result))
                return
            
            oj.element(container, 'div', 'moduletitle', [libraryName + ' library'])
            oj.element(container, 'table', 'modules', [table = oj.element(table, 'tbody')])
            
            JSON.parse(result).forEach(function (file) {
                if (/\.js$/.test(file)) {
                    name = file.replace(/\.js$/, '')
                    if (name === module)
                        oj.element(table, 'tr', ['<td><b>' + name + '</b></td>'])
                    else
                        oj.element(table, 'tr', ['<td><a href="' + url + libraryPath + file + '">' + name + '</a></td>'])
                }
            })
        })
    }
    
    
    doc['generate'] = function(filepath) {
        /**
         *> doc.generate('filepath')
         * 
         * Renders documentation parsed from the specified filepath
         */
        
        var url = '/oj/doc?f=',
            ancestors = os.path.abspath(filepath).split('/'),
            module = ancestors.pop(),
            parent = undefined,
            parentpath,
            siblings = [],
            header = oj.element(document.body, 'div', 'header', [
                oj.element('span', 'version', ['oj/doc'])
            ]),
            left,
            main
        
        
        oj.element(document.body, 'div', 'content', [
            left = oj.element('div', 'left'),
            main = oj.element('div', 'main')
        ])
        
        
        // Calculate parent/module parts
        if (module === '')
            module = ancestors.pop()
        
        if (typeof module !== 'undefined') {
            module = module.replace(/\.js$/, '')
            parent = ancestors.pop()
        }
        
        
        if (typeof parent === 'undefined' || parent === '') {
            oj.element(header, 'a', {'href': url + filepath}, [module])
            libraryIndex(module, filepath, main, url, module)
            return
        }
        
        parentpath = ancestors.join('/') + '/' + parent + '/'
        oj.element(header, 'a', {'href': url + parentpath}, [parent])
        header.innerHTML += ' &gt; '
        oj.element(header, 'a', {'href': url + filepath}, [module])
        
        libraryIndex(parent, parentpath, left, url, module)
        
        file.open(filepath).read(function (result) {
            if (oj.isError(result))
                return print(result)
            
            var description = oj.element(main, 'div', 'description'),
                p,
                example,
                anchor,
                fnpath
            
            result.file.content.match(COMMENTBLOCKS).forEach(function(commentblock) {
                
                commentblock.match(COMMENTLINE).forEach(function (comment) {
                    comment = comment.replace(TRIMLINE, '')
                    
                    if (comment[0] === '*') {
                        
                        oj.element(main, 'div', 'moduletitle', [comment.replace(/\*/, '')])
                        description = oj.element(main, 'div', 'moduleintro')
                        p = undefined
                        example = undefined
                    
                    } else if (comment[0] === '>') {
                        
                        comment = comment.replace(/>/, '')
                        
                        anchor = comment.replace(ANCHORREM, '')
                        anchor = anchor.replace(ANCHORREP, ',')
                        
                        oj.element(main, 'a', 'anchor', {'id': anchor, 'name': anchor, 'href': '#' + anchor}, [
                            oj.element('span', 'function', [javascript.highlight(comment)])
                        ])
                        description = oj.element(main, 'div', 'description')
                        p = undefined
                        example = undefined
                        
                    } else if (comment.replace(WHITESPACE, '') === '') {
                        
                        p = oj.element(description, 'p')
                        example = undefined
                        
                    } else if (comment[0] === '.') {
                        
                        if (example === undefined)
                            example = oj.element(description, 'pre')
                        
                        example.innerHTML += javascript.highlight(comment.replace(/\./, '')) + '\n'
                        p = undefined
                    
                    }  else if (comment[0] === '/') {
                        
                        oj.element(description, 'br')
                        
                    } else {
                        
                        example = undefined
                        if (typeof p === 'undefined')
                            p = oj.element(description, 'p')
                        p.innerHTML += comment
                        
                    }
                })
            })
        })
    }
    
    
    if (oj.main === 'oj/doc') {
        /**
         **oj.main
         *
         * When run as the main application this module will automatically call
         * doc.generate(f), where f is passed as an argument on the URL.
         *
         *. URL:     /?oj/doc&f=/oj/doc.js
         *. oj/term: oj/doc oj/doc.js
         *
         */
        
        var filepath = 'oj/doc.js',
            anchor = ''
        
        oj.args.forEach(function (arg) {
            if (arg[0] === 'f') {
                filepath = arg[1].replace(/#.*$/, '')
                anchor = arg[1].replace(/^.*#/, '')
            }
            if (!/\/$/.test(filepath) && !/\.js$/.test(filepath))
                filepath += '.js'
        })
        
        document.title += ' : ' + os.path.abspath(filepath)
        doc.generate(filepath)
        
        if (anchor.length > 0) {
            anchor = document.getElementById(anchor)
            if (anchor !== null)
                anchor.scrollIntoView()
        }
    }
    
    
    oj.element(document.head, 'style', {'type': 'text/css'}, [
        'body {',
        '  font-family: sans-serif;',
        '  margin: 0;',
        '  color: #222222;',
        '  background: #FFFFFF;',
        '}',
        'a {',
        '  color: #F58F31;',
        '}',
        'a:link    {text-decoration: none;}',
        'a:visited {text-decoration: none;}',
        'a:active  {text-decoration: none;}',
        'a:hover   {text-decoration: underline;}',
        '.header {',
        '  background: #333333;',
        '  border-bottom: 1px solid black;',
        '  height: 20px;',
        '  padding: 5px;',
        '  color: #F58F31;',
        '}',
        '.header a {',
        '  color: #FFFFFF;',
        '}',
        '.content {',
        '  display: table;',
        '  width: 100%;',
        '}',
        '.left {',
        '  display: table-cell;',
        '  width: 150px;',
        '  padding: 5px;',
        '  color: #222222;',
        '  border-right: 1px solid #F2F2F2;',
        '}',
        '.main {',
        '  display: table-cell;',
        '  background: #FFFFFF;',
        '  padding-left: 20px;',
        '  padding-right: 20px;',
        '  padding-top: -50px;',
        '  color: #333333;',
        '}',
        '.moduletitle {',
        '  border-bottom: 1px solid #F2F2F2;',
        '  margin-top: 20px;',
        '  margin-left: -20px;',
        '  margin-right: -20px;',
        '  margin-bottom: 20px;',
        '  font-size: 200%;',
        '  padding-top: 10px;',
        '  padding-left: 20px;',
        '  padding-bottom: 10px;',
        '  color: #F58F31;',
        '}',
        '.modules {',
        '  width: 100%;',
        '}',
        '.modules a {',
        '  font-family: monospace;',
        '  font-style: normal;',
        '  color: blue;',
        '}',
        '.description {',
        '  padding-left: 20px;',
        '}',
        'pre {',
        '  background: #333333;',
        '  color: #ffffff;',
        '  border-top: 1px solid #FB5F22;',
        '  border-bottom: 1px solid #FB5F22;',
        '  padding-top: 10px;',
        '  padding-bottom: 10px;',
        '}',
        '.version {',
        '  float: right;',
        '}',
        '.anchor {',
        '  color: #F58F31;',
        '}',
        '.function {',
        '  color: black;',
        '  padding-top: 10px;',
        '  padding-bottom: 10px;',
        '  font-weight: bold;',
        '}'
    ])
    
    return doc
    
})
